package com.sysd.server.container;

import com.sysd.bean.Message;
import com.sysd.exception.ServiceException;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import static com.sysd.server.container.AttrContainer.channelUserIdAttr;

/**
 * @description: 通道容器，用来保存通道信息
 * @author: bsh
 * @date: 2025/6/5 11:44
 */
@Slf4j
@Component
public class ChannelContainer {

    private final Map<Integer, Channel> chatChannels = new ConcurrentHashMap<>(16);


    /**
     * 设置通道
     *
     * @param userId  id
     * @param channel 通道
     */
    public void putChatChannel(Integer userId, Channel channel) {
        if (null == userId || 0 > userId) {
          throw new ServiceException("添加对象异常!");
        }
        channel.attr(channelUserIdAttr).set(userId);
        chatChannels.put(userId, channel);
    }

    /**
     * 获取通道
     *
     * @param userId 连接的用户id
     * @return res
     */
    public Channel getChatChannels(Integer userId) {
        if (null == userId || userId < 0) {
            throw new ServiceException("获取对象失败!");
        }
        return chatChannels.get(userId);
    }

    /**
     * 删除
     *
     * @param userId id
     */
    public void removeChatChannel(Integer userId) {
        chatChannels.remove(userId);
    }

    /**
     * 删除
     *
     * @param ctx 根据上下文
     */
    public void removeChatChannel(ChannelHandlerContext ctx) {
        Integer userId = ctx.channel().attr(channelUserIdAttr).get();
        if (null != userId) {
            removeChatChannel(userId);
        }
        ctx.close();
        log.info("断开用户{}的连接", null == userId ? "未验证" : userId);
    }

    /**
     * 校验
     *
     * @param ctx 上下文
     * @return 校验结果
     */
    public boolean auth(ChannelHandlerContext ctx) {
        Integer userId = ctx.channel().attr(channelUserIdAttr).get();
        if (null == userId || userId <= 0) {
            return false;
        }
        return Optional.ofNullable(chatChannels.get(userId))
                .map(Channel::isActive).orElse(false);
    }

    /**
     * 写入消息
     *
     * @param userId 用户id
     * @param msg    消息
     */
    public void writeMessage(Integer userId, Message msg) {
        Channel channel = getChatChannels(userId);
        if (null == channel) {
            //todo 发送消息到队列里面转给其他服务器
            return;
        }
        //本服务器的消息直接去进行转发
        channel.writeAndFlush(msg);
    }
}
